package org.wh1tew0lf.vframe.framework;

import java.util.concurrent.ConcurrentHashMap;

import org.wh1tew0lf.vframe.framework.vframeexception.VDataModelManagerNotInitializedException;
import org.wh1tew0lf.vframe.framework.vframeexception.VFrameException;
import org.wh1tew0lf.vframe.framework.vframeexception.VModelClassIsNullException;
import org.wh1tew0lf.vframe.framework.vframeexception.VModelKeyIsNullException;
import org.wh1tew0lf.vframe.framework.vframeexception.VModelNameIsNullException;
import org.wh1tew0lf.vframe.framework.vframeexception.VModelNotAuthorizedException;
import org.wh1tew0lf.vframe.framework.vframeexception.VModelNotFoundException;
import org.wh1tew0lf.vframe.model.datamodel.AbstractDataModel;

public final class VDataModelManager {
	
	private static ConcurrentHashMap<String, Class<? extends AbstractDataModel>> dataModelClassMap;
	private static ConcurrentHashMap<String, String> dataModelKeyMap;
	
	static {
		dataModelClassMap = new ConcurrentHashMap<String, Class<? extends AbstractDataModel>>();
		dataModelKeyMap = new ConcurrentHashMap<String, String>();
	}
	
	public static boolean updateDataModelClass(String dataModelName, Class<? extends AbstractDataModel> dataModelClass, String oldKey, String newKey) throws VFrameException {
		// TODO Log CALL TRACE
		if (dataModelName == null) {
			throw new VModelNameIsNullException();
		}
		if (dataModelClass == null) {
			throw new VModelClassIsNullException();
		}
		if (dataModelClassMap == null || dataModelKeyMap == null) {
			throw new VDataModelManagerNotInitializedException();
		}
		if (newKey == null) {
			throw new VModelKeyIsNullException();
		}
		String storedKey = dataModelKeyMap.get(dataModelName);
		if (storedKey != null && (!storedKey.equals(oldKey))) {
			return false;
		}
		dataModelClassMap.put(dataModelName, dataModelClass);
		dataModelKeyMap.put(dataModelName, newKey);
		storedKey = null;
		return true;
	}
	
	public static boolean removeDataModel(String dataModelName, String key) throws VFrameException {
		if (dataModelName == null) {
			throw new VModelNameIsNullException();
		}
		if (key == null) {
			throw new VModelKeyIsNullException();
		}
		String storedKey = dataModelKeyMap.get(dataModelName);
		if (storedKey == null) {
			throw new VModelNotFoundException(dataModelName);
		}
		if (storedKey.equals(key)) {
			dataModelKeyMap.remove(dataModelName);
			dataModelClassMap.remove(dataModelName);
			return true;
		} else {
			return false;
		}
	}
	
	public static ICache getDataModelCache(String dataModelName, String logicModelName, String logicModelKey) throws VFrameException {
		if (dataModelName == null) {
			throw new VModelNameIsNullException();
		}
		if (!(VLogicModelManager.isAuthorizedLogicModel(logicModelName, logicModelKey))) {
			throw new VModelNotAuthorizedException(logicModelName, logicModelKey);
		}
		return VCacheManager.getCache(dataModelName);
	}
}
